import { menu } from '../../../app/decorator';
import BaseColorShap, { RenderType } from './base/BaseColorShap';

const { ccclass, property, disallowMultiple, executeInEditMode } = cc._decorator;

const min = Math.min;
const abs = Math.abs;
const sign = Math.sign;

const KAPPA90 = 0.5522847493;

@ccclass
@menu(__filename, '矩形')
@disallowMultiple()
@executeInEditMode()
export default class ColorShapRect extends BaseColorShap {

    @property
    _filletRadius = 0;
    @property
    get filletRadius() { return this._filletRadius; }
    set filletRadius(value) {
        this._filletRadius = value;
        this.updateColorShap();
    }

    @property
    _leftUp = true;
    @property({
        visible(this: ColorShapRect) {
            return this.filletRadius > 0;
        }
    })
    get leftUp() { return this._leftUp; }
    set leftUp(value) {
        this._leftUp = value;
        this.updateColorShap();
    }

    @property
    _leftDown = true;
    @property({
        visible(this: ColorShapRect) {
            return this.filletRadius > 0;
        }
    })
    get leftDown() { return this._leftDown; }
    set leftDown(value) {
        this._leftDown = value;
        this.updateColorShap();
    }

    @property
    _rightUp = true;
    @property({
        visible(this: ColorShapRect) {
            return this.filletRadius > 0;
        }
    })
    get rightUp() { return this._rightUp; }
    set rightUp(value) {
        this._rightUp = value;
        this.updateColorShap();
    }

    @property
    _rightDown = true;
    @property({
        visible(this: ColorShapRect) {
            return this.filletRadius > 0;
        }
    })
    get rightDown() { return this._rightDown; }
    set rightDown(value) {
        this._rightDown = value;
        this.updateColorShap();
    }

    onDraw(ctx: cc.Graphics, centerX: number, centerY: number) {
        let x = centerX - this.node.width * 0.5;
        let y = centerY - this.node.height * 0.5;
        let w = this.node.width;
        let h = this.node.height;
        let r = this.filletRadius;

        if (r < 0.1) {
            ctx.rect(x, y, w, h);
        } else {
            if (this.renderType === RenderType.fill && this.leftUp && this._leftDown && this.rightUp && this.rightDown) {
                ctx.roundRect(x, y, w, h, r);
            } else {
                const rx = min(r, abs(w) * 0.5) * sign(w),
                    ry = min(r, abs(h) * 0.5) * sign(h);

                ctx.moveTo(x, y + ry);

                // 左边
                ctx.lineTo(x, y + h - ry);
                // 左上角
                if (this.leftUp) {
                    ctx.bezierCurveTo(x, y + h - ry * (1 - KAPPA90), x + rx * (1 - KAPPA90), y + h, x + rx, y + h);
                } else {
                    ctx.lineTo(x, y + h);
                    ctx.lineTo(x + rx, y + h);
                }
                // 上边
                ctx.lineTo(x + w - rx, y + h);
                // 右上角
                if (this.rightUp) {
                    ctx.bezierCurveTo(x + w - rx * (1 - KAPPA90), y + h, x + w, y + h - ry * (1 - KAPPA90), x + w, y + h - ry);
                } else {
                    ctx.lineTo(x + w, y + h);
                    ctx.lineTo(x + w, y + h - ry);
                }
                // 右边
                ctx.lineTo(x + w, y + ry);
                // 右下角
                if (this.rightDown) {
                    ctx.bezierCurveTo(x + w, y + ry * (1 - KAPPA90), x + w - rx * (1 - KAPPA90), y, x + w - rx, y);
                } else {
                    ctx.lineTo(x + w, y);
                    ctx.lineTo(x + w - rx, y);
                }
                // 下边
                ctx.lineTo(x + rx, y);
                // 左下角
                if (this.leftDown) {
                    ctx.bezierCurveTo(x + rx * (1 - KAPPA90), y, x, y + ry * (1 - KAPPA90), x, y + ry);
                } else {
                    ctx.lineTo(x, y);
                    ctx.moveTo(x, y + ry);
                }

                ctx.close();
            }
        }
    }
}
